<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // 
        function fn1() {
            // 造一个履约态的Promise实例 会就近找then里的回调去回调
            Promise.resolve()
                .then(
                    (value) => {
                        console.log(1, value);

                        // 当前Promise继续履约
                        return 111
                        // return undefined
                    }
                )
                .catch(
                    () => {
                        console.log(2);
                        // return undefined
                    }
                )
                .then(
                    // 接收前面的Promise履约的数据
                    (value) => {
                        console.log(3,value);
                    }
                )
                .finally(
                    ()=>console.log("game over")
                )
                
        }
        // fn1()

        function fn2() {
            Promise.resolve()
                .then(() => {
                    console.log(1);
                    // throw new Error("erro1");
                })
                .catch(() => {
                    console.log(2);
                    // return undefined
                })//无毁约动作（throw reject）即履约
                .then(() => {
                    console.log(3);
                });
        }
        // fn2()

        function fn3() {
            Promise.resolve()
                .then((value) => {
                    console.log(1,value);
                    throw new Error("erro1");
                })
                .then(value=>console.log(value))
                .catch((err) => {
                    console.log(2,err);
                    // return undefined
                })
                .catch(() => {
                    // 注意这里是 catch
                    console.log(3);
                })
                .then((value) => console.log(4,value))
                .finally(
                    ()=>console.log("game over")
                )
        }
        // fn3()

        function fn4() {
            /* 只要是异步函数 返回值必是Promise */
            async function fn() {
                // 同步代码立即执行
                console.log("a");

                // 履约100
                // return 100;
                // console.log("b");

                // // 对外返回一个将来履约100的Promise对象
                // // promise中的执行器代码是同步代码
                return new Promise(
                    // 执行器函数中的代码是同步的!!!
                    (resolve, reject) => {
                        console.log("30");

                        setTimeout(() => {
                            resolve(100);
                        }, 5000);
                    }
                );

                console.log("4");
            }

            (async function () {
                console.log("call 1");//1

                // 调用fn 并立刻得到【一个将来会履约100的Promise对象】
                const a = fn();//a 30

                console.log("call 2");//2

                // 死等Promise履约的结果
                // await 右侧依然是同步代码
                const b = await fn();//a 30

                console.log("call 3");//3
                console.log(a);//p
                console.log(b);//100
            })();

            console.log("hello");
        }
        // fn4()

        function fn5() {
            /* 异步函数走到阻塞处才让出执行权 */
            (async function () {
                try {
                    console.log("start");//1

                    // 阻塞等待身后的promise履约100
                    const a = await 100
                    // const a = await Promise.resolve(100)

                    /* ----- await以下全都相当于写在then回调里的代码！！！---- */

                    /* await以后的代码相当于then回调中的代码!!! */
                    console.log("a", a);//a=100

                    const b = await Promise.resolve(200);
                    console.log("b", b);//b=200

                    // // try中一旦return 就相当于函数终止+履约b
                    // return b
                    // // return之后的东西都执行不到
                    // console.log("hello");

                    // 毁约的结果在catch里
                    const c = await Promise.reject(300);

                    console.log("c", c);
                    console.log("end");
                }

                catch (err) {
                    console.log("catch err", err);//ce300
                }

                console.log("444");//444
            })();

            console.log("GAME OVER!");//2
        }
        // fn5()

        function fn6() {
            console.log(100);

            setTimeout(
                () => {
                    console.log(200);
                }
            );//宏任务 DOM/BOM-API

            Promise.resolve()//立刻同步地得到Promise对象
                .then(
                    () => {
                        console.log(300);
                    }
                );//微任务 promise.then/catch

            console.log(400);
        }
        // fn6()

        function fn7() {
            async function async1() {
                console.log('async1 start')//2

                await 0//-1

                // await以下全都相当于then中的成功回调
                async2()
                console.log('async1 end')//6
            }

            async function async2() {
                console.log('async2')//5
            }

            console.log('script start')//1

            setTimeout(function () {
                console.log('setTimeout')//8
            })

            async1()

            new Promise(
                function (resolve) {
                    /* 执行器中的代码是同步的 */
                    console.log('promise1')//3
                    resolve()//履约undefined
                }
            )
                .then(//-1
                    function () {
                        console.log('promise2')//7
                    }
                )

            console.log('script end')//4
        }
        // fn7()

    </script>
</body>

</html>